//
//  PublishViewModel.swift
//  EyeVisionForPatients
//
//  Created by PMC on 2020/2/16.
//  Copyright © 2020 tao Tao. All rights reserved.
//

import UIKit
import HandyJSON
import Moya

enum UploadImageStatus: Int {
    case none   // 不需要审核
    case wait   // 待审核
    case pass   // 审核通过
    case refuse // 审核不通过
}

/// 上传图片类型
enum UploadImageType: Int {
    case medicalRecord   // 病历图片
    case chat            // 聊天图片
    case avatar          // 头像图片
    case eyePressure
    case eyeVision
    case eyeRefractive
    
    var bucket: Int {
        switch self {
        case .medicalRecord: return 1
        case .chat:          return 9
        case .avatar:        return 3
        case .eyeVision,
             .eyePressure,
             .eyeRefractive: return 1
        }
    }
    
    var type: Int {
        switch self {
        case .medicalRecord: return 15
        case .chat:          return 92
        case .avatar:        return 30
        case .eyePressure:   return 14
        case .eyeVision:     return 15
        case .eyeRefractive: return 16
        }
    }
}

struct reserveResultModel: HandyJSON {
    var scheduleId: String?
}

struct UploadImgModel: HandyJSON {
    var id: String?
    /// 图片id
    var resourceId: String?
    /// 缩略图路径
    var ShareThumbnailUrl: String?
    var shareThumbnailUrl: String?
    /// 原图路径
    var shareUrl: String?
}

struct UploadImgViewModel {
    let model: UploadImgModel
    
    var imgId: String { return model.resourceId ?? "" }
    
    var thumbnailPath: String { return model.ShareThumbnailUrl ?? model.shareThumbnailUrl ?? "" }
    
    var originalPath: String { return model.shareUrl ?? "" }
}

struct UploadAudioModel: HandyJSON {
    var bucket: String?
    var objectName: String?
    var shareUrl: String?
    var time: Int = 0
}

struct UploadAudioViewModel {
    let model: UploadAudioModel
    var shareUrl: String { return model.shareUrl ?? "" }
}

struct PublishViewModel {
    var models: [UploadImgModel] = []
    
    var imgIds: [String] { return models.map { "\($0.resourceId ?? "")" } }
    
    var numberOfItems: Int { return models.count }
    
    func viewModel(for indexPath: IndexPath) -> UploadImgViewModel {
        return UploadImgViewModel(model: models[indexPath.item])
    }
    
    mutating func append(_ model: UploadImgModel) {
        if models.filter({ $0.id == model.id }).isEmpty {
            models.append(model)
        }
    }
    
    mutating func update(_ model: UploadImgModel) {
        guard let index = models.firstIndex(where: { $0.id == model.id }) else { return }
        models[index] = model
    }
    
    mutating func remove(at indexPath: IndexPath) {
        models.remove(at: indexPath.item)
    }
    
    mutating func remove(at model: UploadImgModel) {
        guard let index = models.firstIndex(where: { $0.id == model.id }) else { return }
        models.remove(at: index)
    }
    
    /// 诊断id
    var diagnoseId: String = ""
    /// 医生id
    var doctorId: String = ""
    /// 医生姓名
    var doctorName: String = ""
    /// 科室名称
    var departmentName: String = ""
    /// 医生职称
    var doctorOffice: String = ""
    /// 医生头像
    var thumbnailavatar: String = ""
    
    /// 就诊人id
    var patientId: String = ""
    /// 就诊人姓名
    var patientName: String = ""
    /// 预约时段 排班时间
    var scheduleTime: String = ""
    /// 排班id
    var scheduleId: String = ""

    var desc: String = ""
    
    /// 费用
    var cost: String = ""
    /// 远程门诊日期
    var reserveTime: String = ""
    /// 远程门诊day
    var reserveDay: String = ""
    
    /// 是否有过敏史, 默认false
    var isAllergyHistory: Bool = false
    /// 过敏史
    var allergyHistory: String = ""
    /// 既往史
    var pastHistory: String = ""
    
    var isEnabled: Bool {
        if isAllergyHistory {
            return !patientId.isEmpty && !scheduleId.isEmpty && !desc.isEmpty && !allergyHistory.isEmpty && !cost.isEmpty
        } else {
            return !patientId.isEmpty && !scheduleId.isEmpty && !desc.isEmpty && !cost.isEmpty
        }
    }
    var isAdvisoryEnable: Bool {
        if isAllergyHistory {
            return !patientId.isEmpty && !desc.isEmpty && !allergyHistory.isEmpty
        } else {
            return !patientId.isEmpty && !desc.isEmpty
        }
    }
    var isNurseEnabled: Bool {

        if isAllergyHistory {
            return !patientId.isEmpty && !desc.isEmpty && !allergyHistory.isEmpty
        } else {
            return !patientId.isEmpty && !desc.isEmpty
        }
    }
    
    var isShowDescAlert: Bool {
        if desc.count < 20 {
            return true
        }
        return false
    }
    
    
    var deleteEnabled: Bool = true
    
}

extension PublishViewModel {
    /// 上传图片
    // bucket: 图片桶类型 默认 1
    // type: 图片类型  患者上传-默认 15
    // relationId: 病例id 患者自述默认 1
    // checkStatus: 图片审核状态
    static func uploadImage(image: UIImage,
                            bucket: Int = 1,
                            type: Int = 15,
                            relationId: Int = 1,
                            checkStatus: UploadImageStatus = .none,
                            success: @escaping (_ model: UploadImgModel) -> Void,
                            failure: @escaping (_ errorMsg: String?) -> Void) {
        var formDatas = [MultipartFormData]()
        let imageData = image.jpegData(compressionQuality: 1) ?? Data()
        let fileName = "\(Date.milliseconds).jpg"
        
        let formData = MultipartFormData(provider: .data(imageData), name: "file", fileName: fileName, mimeType: "image/jpeg")
        formDatas.append(formData)
        
        let paras: [String: Any] = ["bucket": bucket,
                                    "type": type,
                                    "relationId": relationId,
                                    "checkStatus": checkStatus.rawValue]
        HttpTool.shared.request(target: ApiManager.uploadImage(formDatas, paras: paras), success: { (json, code) in
            YSGLog("上传图片: \(json)")
            switch code {
            case .failure:
                failure(json["message"].description)
            case .success:
                if let model = JSONDeserializer<UploadImgModel>.deserializeFrom(json: json["data"].description) {
                    success(model)
                } else {
                    failure("请求数据发生错误，稍候重试")
                }
            }
        }) { errorMsg in
            failure(errorMsg)
        }
    }
    
    /// 上传患者病情
    static func uploadNurseCondition(isAllergyHistory:Int,
                                     tbUserId: String,
                                       nurseId: String,
                                       patientId: String,
                                       condition: String,
                                       imgIdsStr: String,
                                       allergyHistory: String,
                                       pastHistory: String,
                                       finished: @escaping (_ msg: String?, _ code: HttpCode) -> Void) {
        let paras = [
            "isAllergy":isAllergyHistory,
            "tbUserId": tbUserId,
            "patientId": patientId,
            "nurseId": nurseId,
            "reason": condition,
            "resourceId": imgIdsStr,
            "pastHistory": pastHistory,
            "allergyHistory": allergyHistory
        ] as [String : Any]
        HttpTool.shared.request(target: ApiManager.uploadNurseCondition(paras: paras), success: { (json, code) in
            finished(json["message"].description, code)
        }) { errorMsg in
            finished(errorMsg, .failure)
        }
    }
    
    
    /// 上传患者病情
    static func uploadPatientCondition(doctorId: String,
                                       patientId: String,
                                       condition: String,
                                       imgIdsStr: String,
                                       diagnoseId: String,
                                       allergyHistory: String,
                                       pastHistory: String,
                                       finished: @escaping (_ msg: String?, _ code: HttpCode) -> Void) {
        let paras = [
            "patientId": patientId,
            "receiverDocId": doctorId,
            "oneselfState": condition,
            "resourceIdList": imgIdsStr,
            "diagnoseId": diagnoseId,
            "pastHistory": pastHistory,
            "allergyHistory": allergyHistory
        ]
        HttpTool.shared.request(target: ApiManager.uploadCondition(paras: paras), success: { (json, code) in
            finished(json["message"].description, code)
        }) { errorMsg in
            finished(errorMsg, .failure)
        }
    }
    
    
    /// 预约号源
    static func reserveDoctorNumber(numberId: String,
                                    patientId: String,
                                    doctorId: String,
                                    departmentId: String,
                                    businessType: Int = 1,
                                    dockingType: Int = 1,
                                    regDocId: String,
                                    finished: @escaping (_ registrationId: reserveResultModel?, _ msg: String?, _ code: HttpCode) -> Void) {
        let paras: [String: Any] = [
            "numberId": numberId,
            "patientId": patientId,
            "docId": doctorId,
            "deptId": departmentId,
            "businessType": businessType,
            "dockingType": dockingType,
            "regDocId": regDocId
        ]
        YSGLog("预约号源 params: \(paras)")
        HttpTool.shared.request(target: ApiManager.reserveDoctorNumber(paras: paras), success: { (json, code) in
            YSGLog("预约号源 json: \(json)")
            if let model = JSONDeserializer<reserveResultModel>.deserializeFrom(json: json["data"].description) {
                finished(model, json["message"].description, code)
            } else {
                finished(nil, json["message"].description, .failure)
            }
        }) { errorMsg in
            YSGLog("预约号源 error: \(errorMsg?.debugDescription ?? "Unknown Error.")")
            finished(nil, errorMsg, .failure)
        }
    }
    
    /// 获取上传图片的 presigned url地址
    /// bucket: 1 - 病历图片  9 - 聊天图片  3 - 头像
    static func getPresignedUrl(imageType: UploadImageType, finished: @escaping (String, String?, HttpCode) -> Void) {
        let params = ["bucket": imageType.bucket]
        YSGLog("获取 presigned url params: \(params)")
        HttpTool.shared.request(target: ApiManager.getPresignedUrl(paras: params), success: { (json, code) in
            YSGLog("获取 presigned url json: \(json)")
            finished(json["data"].description, json["message"].description, code)
        }) { error in
            YSGLog("获取 presigned url error: \(error.debugDescription)")
            finished("", error, .failure)
        }
    }
    
    /// 通过 Presigned Url 上传图片
    static func uploadImageBy(_ image: UIImage, presignedUrl urlStr: String, finished: @escaping (String?, HttpCode) -> Void) {
        let imageData = image.jpegData(compressionQuality: 1) ?? Data()
        
        YSGLog("urlStr: \(urlStr)")
        
        var urlRequest = URLRequest(url: URL(string: urlStr)!)
        urlRequest.httpMethod = "PUT"
        urlRequest.httpBody = imageData
        
        let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            if error != nil {
                YSGLog("通过 Presigned Url 上传图片 error: \(error.debugDescription)")
                finished(error?.localizedDescription, .failure)
            } else {
                finished(nil, .success)
                YSGLog("通过 Presigned Url 上传图片 data: \(String(data: data ?? Data(), encoding: .utf8) ?? "+++---")")
            }
        }
        dataTask.resume()
    }
    
    /// 保存图片到数据库
    /// bucket: 1 - 病历图片  9 - 聊天图片  3 - 头像
    /// type:  15 - 病历图片 92 - 聊天图片 30 - 头像
    static func saveImageToDataBase(objectName: String,
                                    imageType: UploadImageType,
                                    relationId: Int = -1,
                                    introduction: String = "image/png",
                                    size: Double,
                                    checkStatus: UploadImageStatus = .none,
                                    isIm: Int = 0,
                                    finished: @escaping (UploadImgModel?, String?, HttpCode) -> Void)
    {
        let params: [String: Any] = [
            "objectName": objectName,
            "bucket": imageType.bucket,
            "type": imageType.type,
            "relationId": relationId,
            "introduction": introduction,
            "size": size,
            "checkStatus": checkStatus.rawValue,
            "isIm": isIm
        ]
        YSGLog("保存图片到数据库 params: \(params)")
        HttpTool.shared.request(target: ApiManager.saveImageToDataBase(paras: params), success: { (json, code) in
            YSGLog("保存图片到数据库 json: \(json)")
            let model = UploadImgModel.deserialize(from: json["data"].description)
            finished(model, json["message"].description, code)
        }) { error in
            YSGLog("保存图片到数据库 error: \(error.debugDescription)")
            finished(nil, error, .failure)
        }
    }
}
